//
//  LoginViewModel.swift
//  todoios
//
//  Created by qianli on 2025/4/11.
//

import UIKit
import Moya
import SwiftyUserDefaults
import Combine

//登录
class LoginViewModel : ObservableObject{
    static let shared = LoginViewModel()

    var registerResults : BaseData?
    var customerServiceData : CustomerServiceData?
    var nodeNames:[String]? //全部节点
    var subscribeNodes:[String]=[] //订阅的节点
    var nodehealthInfo:[String:Int] = [:]
    var healthNodeList:[QianliNode] = []
    var darwin_reviewing:Bool = true
    var isLogouted:Bool = false //记录是否手动退出登录
    var isDarwined:Bool = false //是否已加载公共参数
    var enableGuestRegister:Bool = false
    
    var getSubNodeListcompletionHandler: ((_ result:Bool) -> Void)?
    
    var url_JKou_Index = 0
    var url_JKou = QianliConfig.SERVIER_URL[0]
    var url_Yaml = "https://api.apiooo.com" //QianliConfig.SUBNODE_URL
    
    var lastErrInfo = ""
    
    private static let logger = NetworkLoggerPlugin(configuration: .init(logOptions: .verbose))
    private let VJKiXGtGCvnK5PQd = MoyaProvider<APIHub>(plugins: [logger])
    
    func W9adTUJTRCiUNKB0(completion: @escaping (Result<BaseData, Error>) -> Void){
        url_JKou_Index = Defaults[\.lastJKouUrlIndex]
        self.VJKiXGtGCvnK5PQd.request(.apiGetPublicSetting){ [weak self] result in
            switch result{
            case .success(let response):
                if let self = self{
                    Defaults[\.lastJKouUrlIndex] = self.url_JKou_Index //表示好用
                    print("getPulicSetting>success:lastJKouUrlIndex=\(self.url_JKou_Index)")
                }
                do{
                    let publicSettingResults = try JSONDecoder().decode(PublicSettingResults.self, from: response.data)
                    if publicSettingResults.code == 0{
                        if let guestData = publicSettingResults.data{
                            self?.darwin_reviewing = guestData.darwinReviewing
                            let frontendUrl = guestData.frontendURL
                            Defaults[\.frontendUrl] = frontendUrl //"https://share.51qianli.com"
                            let backendURL = guestData.backendURL //下载yaml的域名列表,取第1个就行
                            let list = backendURL.components(separatedBy: .newlines)
                            if list.count>0,let firstUrl = list.first{
                                if !firstUrl.isEmpty{
                                    self?.url_Yaml = firstUrl
                                }
                            }
                            let customerURL = guestData.customerURL
                            Defaults[\.customerURL] = customerURL
                            self?.isDarwined = true
                            self?.enableGuestRegister = guestData.enableGuestRegister
                            
                            let result = BaseData(code: publicSettingResults.code, msg: "")
                            completion(.success(result))
                        }else{
                            let result = BaseData(code: -1, msg: "无效数据")
                            completion(.success(result))
                            ZacollectModel.shared.vnveDBhaItvpywSl("getPulicSetting","无效data")
                        }
                        
                    }else{
                        let result = BaseData(code: publicSettingResults.code, msg: publicSettingResults.msg)
                        completion(.success(result))
                        ZacollectModel.shared.vnveDBhaItvpywSl("getPulicSetting","\(publicSettingResults.code)-\(publicSettingResults.msg)")
                    }
                }
                catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("getPulicSetting","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                print("errorCode=\(error.errorCode),msg:\(error.localizedDescription)")
                completion(.failure(error))
                
                let hasAllowedPolicy = Defaults[\.hasAllowedPolicy]
                if hasAllowedPolicy{//已同意隐私政策，说明已经允许使用了
                    self?.lastErrInfo = "getPulicSetting>请求出错:\(error.errorCode)-\(error.localizedDescription)"
                }
                //未授权网络前请求，会触发异常：errorCode=6,msg:URLSessionTask failed with error: 似乎已断开与互联网的连接。
                //error.errorCode = 6,error.localizedDescription = "URLSessionTask failed with error: 未能找到使用指定主机名的服务器。"
            }
        }
    }
    
    //MARK: - 2.游客登录
    func fXMH25bi9pXZ9yVe(completion: @escaping (Result<BaseData, Error>) -> Void){
        let device_id = getDeviceID()
        self.VJKiXGtGCvnK5PQd.request(.apiGuestLogin(device_id: device_id, referrer_code: "kk")){result in
            switch result{
            case .success(let response):
                do {
                    let decoder = JSONDecoder()
//                    decoder.dateDecodingStrategy = .iso8601 //取消date转换，全部保存为string，以免json中iso8601格式异常
                    let loginResults = try decoder.decode(LoginResults.self, from: response.data)
                    if loginResults.code == 0{
                        if let data = loginResults.data{
                            Defaults[\.token] = data.token
                            if let user = data.user{
                                Defaults[\.avatar] = user.avatar
                                Defaults[\.username] = user.userName
                                Defaults[\.invitationCode] = user.invitationCode
                                Defaults[\.memberexpiryat] = user.memberExpiryAt
                                Defaults[\.memberLevel] = user.memberLevel //游客居然是1(后统一改成0了)
                                Defaults[\.isGuset] = user.guest
                                Defaults[\.isTester] = user.tester
                                Defaults[\.maxBindCount] = user.maxDevices
                            }else{
                                ZacollectModel.shared.vnveDBhaItvpywSl("guestLogin","无效User")
                            }
                            
                            completion(.success(BaseData(code: 0, msg: "")))
                        }else{
                            completion(.success(BaseData(code: -1, msg: "用户信息有误")))
                            ZacollectModel.shared.vnveDBhaItvpywSl("guestLogin","无效data")
                        }
                    }else{
                        completion(.success(BaseData(code: loginResults.code, msg: loginResults.msg)))
                        ZacollectModel.shared.vnveDBhaItvpywSl("guestLogin","\(loginResults.code)-\(loginResults.msg)")
                    }
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("guestLogin","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("guestLogin","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    //MARK: - 3.订阅服务列表
    func PM8lDRSw8vhaZtaq(completion: @escaping (Result<BaseData, Error>) -> Void){
        self.VJKiXGtGCvnK5PQd.request(.apiGetCustomerServiceList){ [weak self] result in
            switch result{
            case .success(let response):
                do {
                    let decoder = JSONDecoder()
//                    decoder.dateDecodingStrategy = .iso8601
                    //ISO 8601 是一种国际标准的日期和时间表示方法，它定义了日期和时间的字符串表示形式，像 2023-10-15T12:30:00Z 这样
                    //设置 dateDecodingStrategy 为 .iso8601,这样 JSONDecoder 才能正确地把这些字符串解析成 Swift 的 Date 类型
                    //jsondata={ "date": "2024-04-12T10:00:00Z" }
                    let customerServiceListResults = try decoder.decode(CustomerServiceListResults.self, from: response.data)
                    let code = customerServiceListResults.code
                    if (code != 0){
                        completion(.success(BaseData(code: code, msg: customerServiceListResults.msg)))
                        ZacollectModel.shared.vnveDBhaItvpywSl("getCustomerServiceList","\(code)-\(customerServiceListResults.msg)")
                    }else if let data = customerServiceListResults.data{
                        self?.customerServiceData = data.first
                        if let uuid = self?.customerServiceData?.subUUID{
                            Defaults[\.subuuid] = uuid
                            Qianli_G_SharedMdb.shared.SetSubUUID(uuid: uuid)
                        }
                        if let serverId = self?.customerServiceData?.id{ //服务ID
                            Defaults[\.serverId] = "\(serverId)"
                        }
                        completion(.success(BaseData(code: 0, msg: "")))
                    }else{
                        completion(.success(BaseData(code: -1, msg: LocalizedString("Invalid subscription, please try again later"))))
                        ZacollectModel.shared.vnveDBhaItvpywSl("getCustomerServiceList","无效data")
                    }
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("getCustomerServiceList","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("getCustomerServiceList","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    //MARK: - 4.邮箱验证码
    func ogOuZmnc3tTKZf96(emailCodeRequest: EmailCodeRequest,completion: @escaping (Result<BaseData, Error>) -> Void){
        NetWorkManager.shared.provider.request(.apiGetEmailCode(emailCodeRequest: emailCodeRequest)){ result in
            switch result{
            case .success(let response):
                // 将响应数据转换为 JSON 字典
                do {
                    let decoder = JSONDecoder()
                    let baseData = try decoder.decode(BaseData.self, from: response.data)
                    completion(.success(baseData))
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("getEmailCode","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("getEmailCode","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    //MARK: - 5.注册
    
    //MARK: - 6.重置密码
    func rqw7MMQYipwKZmYo(resetPassword: ResetPasswordRequest, completion: @escaping (Result<BaseData, Error>) -> Void){
        NetWorkManager.shared.provider.request(.apiResetPassword(resetPasswordRequest: resetPassword)){ [weak self] result in
            switch result{
            case .success(let response):
                do{
                    let baseData = try JSONDecoder().decode(BaseData.self, from: response.data)
                    completion(.success(baseData))
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("resetPassword","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("resetPassword","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    //MARK: - 7.账号登录 闭包返回请求结果
    func PToBQUrjD0wWrDlk(loginRequest: LoginRequest, completion: @escaping (Result<LoginResults, Error>) -> Void){
        NetWorkManager.shared.provider.request(.apiLogin(loginRequest: loginRequest)){ result in
            switch result{
            case .success(let response):
                do {
                    let decoder = JSONDecoder()
                    let loginResults = try decoder.decode(LoginResults.self, from: response.data)
                    if let data = loginResults.data{
                        Defaults[\.token] = data.token
                        if let user = data.user{
                            Defaults[\.avatar] = user.avatar
                            Defaults[\.username] = user.userName
                            Defaults[\.invitationCode] = user.invitationCode
                            Defaults[\.memberexpiryat] = user.memberExpiryAt
                            Defaults[\.memberLevel] = user.memberLevel
                            Defaults[\.isGuset] = user.guest
                            Defaults[\.isTester] = user.tester
                            Defaults[\.maxBindCount] = user.maxDevices
                        }else{
                            ZacollectModel.shared.vnveDBhaItvpywSl("emailLogin","无效User")
                        }
                    }else{
                        ZacollectModel.shared.vnveDBhaItvpywSl("emailLogin","无效data")
                    }
                    completion(.success(loginResults))
                    
                    if(loginResults.code != 0){
                        ZacollectModel.shared.vnveDBhaItvpywSl("emailLogin","\(loginResults.code)-\(loginResults.msg)")
                    }
                }catch{
                    completion(.failure(error))
                    QianliUniversalFunc.QianliLog("login.decoder.error: \(error)")
                    ZacollectModel.shared.vnveDBhaItvpywSl("emailLogin","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                QianliUniversalFunc.QianliLog("login.error : \(error)")
                ZacollectModel.shared.vnveDBhaItvpywSl("emailLogin","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    //MARK: - 8.注册账号 异步
    func kfXgRj1Y1WIRI1m7(registerRequest: RegisterRequest, completion: @escaping (Result<LoginResults, Error>) -> Void) {
        NetWorkManager.shared.provider.request(.apiRegisterAccount(registerRequest: registerRequest)) {result in
            switch result {
            case .success(let response):
                do {
//                    let decoder = JSONDecoder()
//                    let baseData = try decoder.decode(BaseData.self, from: response.data)
//                    completion(.success(baseData))
                    let decoder = JSONDecoder()
                    let loginResults = try decoder.decode(LoginResults.self, from: response.data)//为方便用户，服务做了注册后自动登录操作
                    if let data = loginResults.data{
                        Defaults[\.token] = data.token
                        if let user = data.user{
                            Defaults[\.avatar] = user.avatar
                            Defaults[\.username] = user.userName
                            Defaults[\.invitationCode] = user.invitationCode
                            Defaults[\.memberexpiryat] = user.memberExpiryAt
                            Defaults[\.memberLevel] = user.memberLevel
                            Defaults[\.isGuset] = user.guest
                            Defaults[\.isTester] = user.tester
                            Defaults[\.maxBindCount] = user.maxDevices
                        }else{
                            ZacollectModel.shared.vnveDBhaItvpywSl("registerRequest","无效User")
                        }
                    }else{
                        ZacollectModel.shared.vnveDBhaItvpywSl("registerRequest","无效data")
                    }
                    completion(.success(loginResults))
                    
                    if(loginResults.code != 0){
                        ZacollectModel.shared.vnveDBhaItvpywSl("registerRequest","\(loginResults.code)-\(loginResults.msg)")
                    }
                } catch {
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("registerAccount","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("registerAccount","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    
    //MARK: - 9.获取订阅链接(弃用)
    func aM8Tke8AFGE2cU5X(){
        self.VJKiXGtGCvnK5PQd.request(.apiGetSubNodeList){ [weak self] result in
            switch result{
            case .success(let response):
                do {
                    QianliUniversalFunc.QianliLog("getSubNodeList success : \(response)")
                    // 假设 response.data 是 Base64 编码的字符串
                    let base64String = String(data: response.data, encoding: .utf8)
                    if let base64String = base64String,
                       let decodedData = Data(base64Encoded: base64String) {
                        let decodedString = String(data: decodedData, encoding: .utf8)
                        if let decodedString = decodedString {
                            // 进行 URL 解码
                            if let urlDecodedString = decodedString.removingPercentEncoding {
                                QianliUniversalFunc.QianliLog("最终解码后的字符串: \(urlDecodedString)")
                                let dataArray = urlDecodedString.components(separatedBy:.newlines).filter {!$0.isEmpty}
//                                Defaults[\.nodelist] = dataArray
                                self?.getSubNodeListcompletionHandler?(true)
                            } else {
                                print("getSubNodeList.error : URL解码失败")
                            }
                        } else {
                            print("getSubNodeList.error : Base64解码后无法转换为字符串")
                        }
                    } else {
                        print("getSubNodeList.error : Base64解码失败")
                    }
                } catch {
                    print("getSubNodeList.error : \(error)")
                    ZacollectModel.shared.vnveDBhaItvpywSl("getSubNodeList","处理出错:\(error.localizedDescription)")
                }
                
            case .failure(let error):
                ZacollectModel.shared.vnveDBhaItvpywSl("getSubNodeList","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    func ZPu2bfdDaaLbgpbM(completion: @escaping (Result<BaseData, Error>) -> Void){
        self.VJKiXGtGCvnK5PQd.request(.apiGetNodeNames){ [weak self] result in
            switch result{
            case .success(let response):
                do {
                    let decoder = JSONDecoder()
                    let nodeResults = try decoder.decode(NodeNamesData.self, from: response.data)
                    let code = nodeResults.code
                    if (code != 0){
                        completion(.success(BaseData(code: code, msg: nodeResults.msg)))
                        ZacollectModel.shared.vnveDBhaItvpywSl("getNodeNames","\(code)-\(nodeResults.msg)")
                    }else if let data = nodeResults.data{
                        if data.count>0{
                            self?.nodeNames = data
                        }
                        completion(.success(BaseData(code: 0, msg: "")))
                    }else{
                        completion(.success(BaseData(code: -1, msg: LocalizedString("Node data not obtained, please try again later"))))
                        ZacollectModel.shared.vnveDBhaItvpywSl("getNodeNames","无效data")
                    }
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("getNodeNames","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("getNodeNames","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    func vFuidwaT3K4CZ0P6(serverId:String,completion: @escaping (Result<BaseData, Error>) -> Void){
        self.VJKiXGtGCvnK5PQd.request(.apiGetSubscribeNodeList(serverId: serverId)){ [weak self] result in
            switch result{
            case .success(let response):
                do {
                    // 解析 JSON 为字典
                    if let json = try JSONSerialization.jsonObject(with: response.data, options: []) as? [String: Any]{
                        if json["code"] as? Int == 0{
                            if let dataArray = json["data"] as? Array<Any> {
                                self?.subscribeNodes.removeAll()
                                self?.healthNodeList.removeAll()
                                for perDict in dataArray {
                                    if let dataDict = perDict as? [String: Any]{
//                                        print("perDict:\n\(dataDict)")
                                        if let remarks = dataDict["remarks"] as? String{
                                            self?.subscribeNodes.append(remarks)
                                            
                                            var heathid = "0"
                                            if let nodeid = dataDict["remarks"] as? Int{
                                                heathid = "\(nodeid)"
                                            }
                                            if let host = dataDict["address"] as? String,let port = dataDict["port"] as? Int{
                                                self?.healthNodeList.append(QianliNode(id: heathid, name: remarks, host: host, port: port));
                                            }
                                        }
                                        
                                    }
                                    
                                }
                                completion(.success(BaseData(code: 0, msg: "")))
                            } else {
                                completion(.success(BaseData(code: -1, msg: "getSubscribeNodeList:Invalid")))
                                ZacollectModel.shared.vnveDBhaItvpywSl("getSubscribeNodeList","无效data")
                            }
                        }else{
                            if let iCode = json["code"] as? Int,let msg = json["msg"] as? String{
                                completion(.success(BaseData(code: iCode, msg: msg)))
                                ZacollectModel.shared.vnveDBhaItvpywSl("getSubscribeNodeList","\(iCode)-\(msg)")
                            }else{
                                completion(.success(BaseData(code: -2, msg: "getSubscribeNodeList:Failed")))
                                ZacollectModel.shared.vnveDBhaItvpywSl("getSubscribeNodeList","未知code或msg")
                            }
                        }
                    }
                } catch{
                    completion(.failure(error))
                    ZacollectModel.shared.vnveDBhaItvpywSl("getSubscribeNodeList","处理出错:\(error.localizedDescription)")
                }
            case .failure(let error):
                completion(.failure(error))
                ZacollectModel.shared.vnveDBhaItvpywSl("getSubscribeNodeList","请求出错:\(error.localizedDescription)")
            }
        }
    }
    
    
}
